#include "stdafx.h"
#include "utils/numberparser.hpp"
#include "stdlib/exception.hpp"
using namespace JHCPP::stdlib::jhException;

#if defined(_MSC_VER) || defined(__MINGW32__ )
	#define I64_FMT "I64"
#else
	#define I64_FMT "ll"
#endif

namespace JHCPP
{
	namespace utils
	{
		int CNumberParser::parse(const std::string& s)
		{
			int result;
			if (tryParse(s, result))
				return result;
			else
				throw SyntaxException("Not a valid integer", s);
		}

		bool CNumberParser::tryParse(const std::string& s, int& value)
		{
			char temp;
			return std::sscanf(s.c_str(), "%d%c", &value, &temp) == 1;
		}

		unsigned CNumberParser::parseUnsigned(const std::string& s)
		{
			unsigned result;
			if (tryParseUnsigned(s, result))
				return result;
			else
				throw SyntaxException("Not a valid unsigned integer", s);
		}

		bool CNumberParser::tryParseUnsigned(const std::string& s, unsigned& value)
		{
			char temp;
			return std::sscanf(s.c_str(), "%u%c", &value, &temp) == 1;
		}

		Int64 CNumberParser::parse64(const std::string& s)
		{
			Int64 result;
			if (tryParse64(s, result))
				return result;
			else
				throw SyntaxException("Not a valid integer", s);
		}

		bool CNumberParser::tryParse64(const std::string& s, Int64& value)
		{
			char temp;
			return std::sscanf(s.c_str(), "%" I64_FMT "d%c", &value, &temp) == 1;
		}

		UInt64 CNumberParser::parseUnsigned64(const std::string& s)
		{
			UInt64 result;
			if (tryParseUnsigned64(s, result))
				return result;
			else
				throw SyntaxException("Not a valid unsigned integer", s);
		}

		bool CNumberParser::tryParseUnsigned64(const std::string& s, UInt64& value)
		{
			char temp;
			return std::sscanf(s.c_str(), "%" I64_FMT "u%c", &value, &temp) == 1;
		}

		unsigned CNumberParser::parseHex(const std::string& s)
		{
			unsigned result;
			if (tryParseHex(s, result))
				return result;
			else
				throw SyntaxException("Not a valid hexadecimal integer", s);
		}

		bool CNumberParser::tryParseHex(const std::string& s, unsigned& value)
		{
			char temp;
			return std::sscanf(s.c_str(), "%x%c", &value, &temp) == 1;
		}

		UInt64 CNumberParser::parseHex64(const std::string& s)
		{
			UInt64 result;
			if (tryParseHex64(s, result))
				return result;
			else
				throw SyntaxException("Not a valid hexadecimal integer", s);
		}

		bool CNumberParser::tryParseHex64(const std::string& s, UInt64& value)
		{
			char temp;
			return std::sscanf(s.c_str(), "%" I64_FMT "x%c", &value, &temp) == 1;
		}
	}//end of namespace utils
}//end of namespace JHCPP
